www.gusucode.com > VC++ 远程桌面抓图_截取远程桌面图片-源码程序 > VC++ 远程桌面抓图_截取远程桌面图片-源码程序/code/SreenClient/SreenClientDlg.cpp

    // SreenClientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SreenClient.h"
#include "SreenClientDlg.h"
// Download by http://www.NewXing.com
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSreenClientDlg dialog

CSreenClientDlg::CSreenClientDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSreenClientDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSreenClientDlg)
	m_ip = _T("");
	m_port = 0;
	m_usrpwd = _T("");
	m_usrname = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSreenClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSreenClientDlg)
	DDX_Control(pDX, IDC_SCROLLBAR2, m_hbar);
	DDX_Control(pDX, IDC_SCROLLBAR1, m_vbar);
	DDX_Text(pDX, IDC_EDIT_IP, m_ip);
	DDX_Text(pDX, IDC_EDIT_PORT, m_port);
	DDX_Text(pDX, IDC_EDIT_PWD, m_usrpwd);
	DDX_Text(pDX, IDC_EDIT_USRNAME, m_usrname);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSreenClientDlg, CDialog)
	//{{AFX_MSG_MAP(CSreenClientDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_CONNECT, OnButtonConnect)
	ON_BN_CLICKED(IDC_BUTTON_GETCAP, OnButtonGetcap)
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
	ON_EN_CHANGE(IDC_EDIT_PORT, OnChangeEditPort)
	ON_BN_CLICKED(IDC_BUTTON_SAVEBMP, OnButtonSavebmp)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSreenClientDlg message handlers

BOOL CSreenClientDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	pclient=NULL;
	m_ip="127.0.0.1";
	m_port=3009;
	m_usrpwd="123";
	m_usrname="aaa";
	UpdateData(FALSE);
	m_pBIH=NULL;
    m_pDibBits=NULL;

    m_pDib=NULL;
    pklen=sizeof(NETPACKAGE);
	lbitsOffset=0;
    capflag=0;
	bcontrol=0;
    initDrawParam();
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSreenClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSreenClientDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSreenClientDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CSreenClientDlg::OnButtonConnect() 
{
	// TODO: Add your control notification handler code here
	CString name;
	
	GetDlgItemText(IDC_BUTTON_CONNECT,name);
	UpdateData(TRUE);
	if(name=="连接")
	{
    	pclient=new CClientSock;
	    pclient->Create();//创建普通的SOCKET
	    pklen=sizeof(NETPACKAGE);
	    pclient->setdlg(this,1,pklen);
		int rt=pclient->Connect(m_ip,m_port);//连接服务端
		if(rt==1)
		{
	    	strcpy(usrinfo.name,m_usrname.GetBuffer(0));
			strcpy(usrinfo.password,m_usrpwd.GetBuffer(0));
			usrinfo.uport=3100;
			pclient->SendCommandData(1,(char*)&usrinfo,sizeof(USERINFO));

		}
		else
        {
             AfxMessageBox("连接服务器失败!");
	         SetDlgItemText(IDC_BUTTON_CONNECT,"连接");
		}
	}
	else
	{
		pclient->SendCommandData(2,(char*)&usrinfo,sizeof(USERINFO));
		pclient->Close();
		delete pclient;
		pclient=NULL;

        if(m_pDib!=NULL)
			delete[] m_pDib;
        m_pDib=NULL;
		SetDlgItemText(IDC_BUTTON_CONNECT,"连接");
	}

}

void CSreenClientDlg::myRecvData(CClientSock *pc)
{
    CString tstr;
	pc->GetPackage((char*)&usrpack);
	switch(usrpack.type)
	{
	case 1://用户登录
          memcpy(&usrinfo,usrpack.buf,sizeof(usrinfo));
		 // tstr.Format("Ack Login:%s,%s,%d",usrinfo.name,usrinfo.password,usrinfo.uport);
		//  AfxMessageBox(tstr);
		  tstr=usrinfo.password;
		  if(tstr=="passwork ok"&m_usrname=="aaa")
          {
			  AfxMessageBox("登录成功!");//密码正确
			  SetDlgItemText(IDC_BUTTON_CONNECT,"退出连接");
		  }
		  else
              AfxMessageBox("用户名或密码错误,请重新登录!");////密码错误
		  break;
	case 2://用户退出
          memcpy(&usrinfo,usrpack.buf,sizeof(usrinfo));
		  tstr.Format("OK Logoff",usrinfo.name,usrinfo.password,usrinfo.uport);
		  AfxMessageBox(tstr);
		  break;
    case 3:
		 memcpy(&cheader,usrpack.buf,sizeof(cheader));
		 if(m_pDib==NULL)
		 {
	         int m_dwDibSize = cheader.filelength + sizeof( BITMAPINFOHEADER )+1000;
	         m_pDib = new unsigned char[m_dwDibSize];   
	         m_pDibBits=&m_pDib[sizeof(BITMAPINFOHEADER )];
		 }
		 lbitsOffset=0;
		 break;
    case 4:
		  if(m_pDibBits!=NULL&&usrpack.len==50000)
			{ 
			   memcpy(&m_pDibBits[lbitsOffset],usrpack.buf,usrpack.len);
			   lbitsOffset=lbitsOffset+usrpack.len;
			}
		  break;
    case 5:
          if(m_pDibBits!=NULL)
			{ 
			   memcpy(&m_pDibBits[lbitsOffset],usrpack.buf,usrpack.len);
			   lbitsOffset=lbitsOffset+usrpack.len;
			}
		    if(lbitsOffset!=cheader.filelength)//接收错误
			{
				tstr.Format("Error:%d!=%d",lbitsOffset,cheader.filelength);
		        AfxMessageBox(tstr);
				return;
			}
			 m_pBIH = (BITMAPINFOHEADER*)m_pDib;
	         m_pBIH->biSize= sizeof(BITMAPINFOHEADER);
	         m_pBIH->biWidth	= cheader.width;
	         m_pBIH->biHeight= cheader.height;
	         m_pBIH->biPlanes= 1;
	         m_pBIH->biBitCount= 24;
	         m_pBIH->biCompression= BI_RGB;
	         m_pBIH->biSizeImage	= 0;
	         m_pBIH->biXPelsPerMeter	= 0;
	         m_pBIH->biYPelsPerMeter	= 0;
	         m_pBIH->biClrUsed= 0;
	         m_pBIH->biClrImportant= 0;
             initDrawSreen();
             break;  
	}

}



void CSreenClientDlg::OnButtonGetcap() 
{
	// TODO: Add your control notification handler code here

	if(pclient!=NULL)
    	pclient->SendCommandData(3,(char*)&usrinfo,sizeof(USERINFO));

/*	CClientDC dc(this);
	CRect rect;
	this->GetClientRect(&rect);
    int w=rect.Width();
	int h=rect.Height();
	CRect rect1,rect2;
    GetDlgItem(IDC_SCROLLBAR1)->GetClientRect(&rect1);
    GetDlgItem(IDC_SCROLLBAR2)->GetClientRect(&rect2);
    w=w-rect1.Width()-15;
	h=h-rect2.Height()-15;
	dc.MoveTo(0,75);
	dc.LineTo(w,75);
	dc.LineTo(w,h);
	dc.LineTo(0,h);
	dc.LineTo(0,75);*/

}

void CSreenClientDlg::OnButtonSavebmp() 
{
	// TODO: Add your control notification handler code here
	char szFilter[]="All files (*.*)|*.*|bmp files(*.bmp)|*.bmp||";


	CFileDialog fd(false,"bmp","aaa",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL);
	if(IDOK==fd.DoModal())
	{
		m_filename=fd.GetPathName();

        CapSreen();

		WriteBmpToFile(hBitmap,m_filename);
		UpdateData(FALSE);
	}
}

void CSreenClientDlg::WriteBmpToFile(HBITMAP hBitmap, CString strFileName)
{
	HDC hDC =::CreateDC("DISPLAY",NULL,NULL,NULL); 
    int iBits = ::GetDeviceCaps(hDC, BITSPIXEL) * ::GetDeviceCaps(hDC, PLANES);//当前分辨率下每个像素所占字节数  
    ::DeleteDC(hDC);

    WORD   wBitCount;   //位图中每个像素所占字节数    
    if (iBits <= 1)
		wBitCount = 1;
    else if (iBits <= 4)
		wBitCount = 4;
    else if (iBits <= 8)
		wBitCount = 8;
    else if (iBits <= 24)
		wBitCount = 24;
    else
		wBitCount = iBits;
		    
	DWORD   dwPaletteSize=0;	//调色板大小, 位图中像素字节大小 
    if (wBitCount <= 8)		
		dwPaletteSize = (1 << wBitCount) *	sizeof(RGBQUAD);	
	

	BITMAP  bm;        //位图属性结构
    ::GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);  

    
	BITMAPINFOHEADER   bi,bi1;       //位图信息头结构     
	bi.biSize            = sizeof(BITMAPINFOHEADER);  
    bi.biWidth           = bm.bmWidth;
    bi.biHeight          = bm.bmHeight;
    bi.biPlanes          = 1;
    bi.biBitCount        = wBitCount;
    bi.biCompression     = BI_RGB; //BI_RGB表示位图没有压缩
    bi.biSizeImage       = 0;
    bi.biXPelsPerMeter   = 0;
    bi.biYPelsPerMeter   = 0;
    bi.biClrUsed         = 0;
    bi.biClrImportant    = 0;
	bi1=bi;
	bi1.biBitCount=24;
	
    DWORD dwBmBitsSize = ((bm.bmWidth * wBitCount+31)/32) * 4 * bm.bmHeight;    
    HANDLE hDib  = ::GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));  //为位图内容分配内存
    LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbi = bi;
	
    HANDLE hPal = ::GetStockObject(DEFAULT_PALETTE);  // 处理调色板 
	HANDLE  hOldPal=NULL; 
    if (hPal)
    {
		hDC = ::GetDC(NULL);
		hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE);
		RealizePalette(hDC);
    }
	int nOutputBytes = 0;
   
    ::GetDIBits(hDC, hBitmap, 0, (UINT) bm.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,(BITMAPINFO*)lpbi,DIB_RGB_COLORS);// 获取该调色板下新的像素值
    if (hOldPal)//恢复调色板
    {
		SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
		RealizePalette(hDC);
		::ReleaseDC(NULL, hDC);
    }
   
	BITMAPFILEHEADER   bmfHdr; //位图文件头结构     
	bmfHdr.bfType = 0x4D42;  // "BM"  	// 设置位图文件头
	DWORD dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;  
	bmfHdr.bfSize = dwDIBSize;
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
	
	HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);//创建位图文件   
	DWORD dwWritten;
	WriteFile(hFile, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);	// 写入位图文件头
	WriteFile(hFile, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);// 写入位图文件其余内容


	GlobalUnlock(hDib);   //清除   
	GlobalFree(hDib);
	CloseHandle(hFile); 
   

}


void CSreenClientDlg::initDrawSreen()
{
    m_width=m_pBIH->biWidth;;
	m_height=m_pBIH->biHeight;

	scrylm=m_height-cheight;
	if(scrylm<0)
		scrylm=0;
    scrxlm=m_width-cwidth;
	if(scrxlm<0)
		scrxlm=0;

//	scrx=0;
//	scry=0;

	m_vbar.SetScrollRange(0,scrylm,TRUE);
	m_vbar.SetScrollPos(scry,TRUE);
	m_hbar.SetScrollRange(0,scrxlm,TRUE);
	m_hbar.SetScrollPos(scrx,TRUE);
	UpdateData(FALSE);
	capflag=1;
	drawSreen();

}

void CSreenClientDlg::initDrawParam()
{
	CRect rect;
	GetClientRect(&rect);
    int w=rect.Width();
	int h=rect.Height();
	CRect rect1,rect2;
    GetDlgItem(IDC_SCROLLBAR1)->GetClientRect(&rect1);
    GetDlgItem(IDC_SCROLLBAR2)->GetClientRect(&rect2);
     cwidth=w-rect1.Width()-15;
	cheight=h-rect2.Height()-90;
//	 cwidth=655-15;
//	 cheight=570-90;
	scrx=0;
	scry=0;
	scrylm=1000;
    scrxlm=1000;
	m_vbar.SetScrollRange(0,scrylm,TRUE);
	m_vbar.SetScrollPos(0,TRUE);
	m_hbar.SetScrollRange(0,scrxlm,TRUE);
	m_hbar.SetScrollPos(0,TRUE);
	UpdateData(FALSE);

}

void CSreenClientDlg::drawSreen()
{
	if(m_pBIH==NULL||m_pDibBits==NULL)
		return;
    if(capflag==0)
		return;
	 CDC *pdc=GetDC();
	// Use StretchDIBits to draw the Dib.
	 StretchDIBits( pdc->m_hDC, 0, 75,
		cwidth, cheight,
		scrx, scry,
		cwidth, cheight,
		m_pDibBits,
		(BITMAPINFO *)m_pBIH,
		BI_RGB, SRCCOPY );
	 ReleaseDC(pdc);

	
}

void CSreenClientDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	    int nPos1=m_vbar.GetScrollPos();
		if(nSBCode==SB_LINEDOWN)
		{
			scry=scry+10;
			if(scry>scrylm)
				scry=scrylm;
			nPos1=scry;
			drawSreen();
			 
		}
		if(nSBCode==SB_LINEUP)
		{
			scry=scry-10;
			if(scry<0)
				scry=0;
			nPos1=scry;
			drawSreen();
		
		}
		if(nSBCode==SB_THUMBTRACK)
		{
			scry=nPos;
			nPos1=nPos;
			if(nPos1>scrylm)
                nPos1=scrylm;
			if(scry<0)
				scry=0;
			if(scry>scrylm)
				scry=scrylm;
			nPos1=scry;
			drawSreen();
			
		}
         m_vbar.SetScrollPos(nPos1);

	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CSreenClientDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	int nPos1=m_hbar.GetScrollPos();
		if(nSBCode==SB_LINERIGHT)
		{
			scrx=scrx+10;
			if(scrx>scrxlm)
				scrx=scrxlm;
		     nPos1=scrx;
			 drawSreen();
		}
		if(nSBCode==SB_LINELEFT)
		{
			scrx=scrx-10;
			if(scrx<0)
				scrx=0;
			 nPos1=scrx;
			 drawSreen();
		}
		if(nSBCode==SB_THUMBTRACK)
		{
			scrx=nPos;
			nPos1=nPos;
			if(scrx<0)
				scrx=0;
			if(scrx>scrxlm)
				scrx=scrxlm;
			 nPos1=scrx;
			drawSreen();
		
		}
		m_hbar.SetScrollPos(nPos1,TRUE);

	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}


void CSreenClientDlg::OnChangeEditPort() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	
}

void CSreenClientDlg::CapSreen()
{
	HWND hWnd =::GetActiveWindow();
	/*::GetTopWindow(NULL);*///获得屏幕的HWND.
	HDC hScreenDC = ::GetDC(hWnd);   //获得屏幕的HDC.
	HDC MemDC = ::CreateCompatibleDC(hScreenDC);
	RECT rect; 
	::GetWindowRect(hWnd,&rect);
	SIZE screensize;
	screensize.cx=rect.right-rect.left;
	screensize.cy=rect.bottom-rect.top;
	hBitmap = ::CreateCompatibleBitmap(hScreenDC,screensize.cx,screensize.cy);
	HGDIOBJ hOldBMP = ::SelectObject(MemDC,hBitmap);
	::BitBlt(MemDC,0,0,screensize.cx,screensize.cy,hScreenDC,rect.left,rect.top,SRCCOPY);
	::SelectObject(MemDC,hOldBMP);
	::DeleteObject(MemDC);
	::ReleaseDC(hWnd,hScreenDC);
}